package com.example.ssmxuankeback.service.impl;

import com.example.ssmxuankeback.interfaces.IEnrollmentMapper;
import org.springframework.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.ssmxuankeback.common.RestBean;
import com.example.ssmxuankeback.dto.EnrollmentDTO;
import com.example.ssmxuankeback.dto.EnrollmentPageQueryDTO;;
import com.example.ssmxuankeback.entity.Enrollment;
import com.example.ssmxuankeback.exception.BusinessException;
import com.example.ssmxuankeback.mapper.EnrollmentMapper;
import com.example.ssmxuankeback.service.EnrollmentService;
import com.example.ssmxuankeback.vo.EnrollmentVO;
import com.example.ssmxuankeback.vo.PageVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class EnrollmentServiceImpl
        extends ServiceImpl<EnrollmentMapper, Enrollment>
        implements EnrollmentService {

    private final EnrollmentMapper enrollmentMapper;

    @Override
    public RestBean<EnrollmentVO> addEnrollment(EnrollmentDTO dto) {
        // 检查是否已选课
        LambdaQueryWrapper<Enrollment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Enrollment::getStudentId, dto.getStudentId())
                .eq(Enrollment::getCourseId, dto.getCourseId());
        if (enrollmentMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException("该学生已选此课程");
        }

        // DTO转Entity（状态默认为1-有效，时间由MyBatis自动填充）
        Enrollment entity = new Enrollment();
        BeanUtils.copyProperties(dto, entity);
        entity.setStatus(1); // 初始状态为有效

        enrollmentMapper.insert(entity);
        return RestBean.success(convertToVO(entity));
    }

    @Override
    public RestBean<EnrollmentVO> cancelEnrollment(Long enrollId) {
        Enrollment entity = enrollmentMapper.selectById(enrollId);
        if (entity == null) {
            throw new BusinessException("选课记录不存在");
        }
        if (entity.getStatus() == 0) {
            throw new BusinessException("该选课记录已退选");
        }

        // 更新状态为0-退选
        LambdaUpdateWrapper<Enrollment> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Enrollment::getStatus, 0)
                .eq(Enrollment::getEnrollId, enrollId);
        enrollmentMapper.update(null, updateWrapper);

        entity.setStatus(0);
        return RestBean.success(convertToVO(entity));
    }

    @Override
    public RestBean<PageVO<EnrollmentVO>> listByPage(EnrollmentPageQueryDTO queryDTO) {
        Page<Enrollment> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        LambdaQueryWrapper<Enrollment> wrapper = new LambdaQueryWrapper<>();

        // 筛选条件
        if (queryDTO.getStudentId() != null) {
            wrapper.eq(Enrollment::getStudentId, queryDTO.getStudentId());
        }
        if (queryDTO.getCourseId() != null) {
            wrapper.eq(Enrollment::getCourseId, queryDTO.getCourseId());
        }
        if (queryDTO.getStatus() != null) {
            wrapper.eq(Enrollment::getStatus, queryDTO.getStatus());
        }

        // 排序
        if (StringUtils.hasText(queryDTO.getSortBy())) {
            String order = "asc".equalsIgnoreCase(queryDTO.getSortOrder()) ? "ASC" : "DESC";
            wrapper.orderBy(true, "asc".equalsIgnoreCase(order), getSortField(queryDTO.getSortBy()));
        }

        IPage<Enrollment> pageResult = enrollmentMapper.selectPage(page, wrapper);
        List<EnrollmentVO> voList = pageResult.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        PageVO<EnrollmentVO> pageVO = PageVO.<EnrollmentVO>builder()
                .total(pageResult.getTotal())
                .pages(pageResult.getPages())
                .records(voList)
                .build();

        return RestBean.success(pageVO);
    }

    @Override
    public RestBean<List<EnrollmentVO>> getByStudentId(Long studentId) {
        LambdaQueryWrapper<Enrollment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Enrollment::getStudentId, studentId);
        List<Enrollment> enrollments = enrollmentMapper.selectList(wrapper);
        return RestBean.success(convertToVOList(enrollments));
    }

    @Override
    public RestBean<List<EnrollmentVO>> getByCourseId(Long courseId) {
        LambdaQueryWrapper<Enrollment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Enrollment::getCourseId, courseId);
        List<Enrollment> enrollments = enrollmentMapper.selectList(wrapper);
        return RestBean.success(convertToVOList(enrollments));
    }

    // -------------------- 工具方法 --------------------
    private EnrollmentVO convertToVO(Enrollment entity) {
        return IEnrollmentMapper.INSTANCT.entityToVO(entity);
    }

    private List<EnrollmentVO> convertToVOList(List<Enrollment> entities) {
        return entities.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    /**
     * 安全获取排序字段（白名单校验）
     */
    private SFunction<Enrollment, ?> getSortField(String sortBy) {
        return switch (sortBy.toLowerCase()) {
            case "enrolltime" -> Enrollment::getEnrollTime;
            case "status" -> Enrollment::getStatus;
            default -> Enrollment::getEnrollId;
        };
    }
}